# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import json
import time
from typing import List
from pydantic import TypeAdapter
from tortoise.expressions import Q
from exception import AppException
from hypertext import PagingResult
from common.enums.pay import PayEnum
from common.utils.tools import ToolsUtil
from common.utils.config import ConfigUtil
from common.models.market import RechargeOrderModel
from common.models.market import RechargePackageModel
from apps.api.schemas import recharge_schema as schema


class RechargeService:
    """ 充值服务类 """

    @classmethod
    async def package(cls) -> List[schema.RechargePackageVo]:
        """
        发起充值

        Returns:
            List[schema.RechargePackageVo]: 套餐列表Vo。

        Author:
            zero
        """
        lists = (await RechargePackageModel
                 .filter(is_disable=0)
                 .filter(is_delete=0)
                 .order_by("-sort", "-id")
                 .all())

        return [TypeAdapter(schema.RechargePackageVo).validate_python(item.__dict__) for item in lists]

    @classmethod
    async def place(cls, user_id: int, terminal: int, post: schema.RechargePlaceIn) -> schema.RechargePlaceVo:
        """
        发起充值

        Args:
            user_id (int): 用户ID。
            terminal (int): 操作平台。
            post (schema.RechargeIn): 充值参数。

        Returns:
            schema.RechargePlaceVo: 下单结果Vo。

        Author:
            zero
        """
        status = int(await ConfigUtil.get("recharge", "status", 0))
        if not status:
            raise AppException("充值通道已关闭")

        # 查询套餐
        package = await RechargePackageModel.filter(id=post.package_id, is_delete=0).first()
        if not package:
            raise AppException("套餐不存在")
        if package.is_disable:
            raise AppException("套餐已下架")

        # 创建订单
        order = await RechargeOrderModel.create(
            user_id=user_id,
            terminal=terminal,
            order_sn=await ToolsUtil.make_order_sn(RechargeOrderModel, "order_sn"),
            pay_way=PayEnum.WAY_MNP,
            package_id=post.package_id,
            order_amount=package.sell_price,
            paid_amount=package.sell_price,
            points_num=package.points_num,
            train_num=package.train_num,
            robot_num=package.robot_num,
            know_num=package.know_num,
            create_time=int(time.time()),
            update_time=int(time.time()),
            snapshot=json.dumps({
                "name": package.name,
                "tags": package.tags,
                "sell_price": str(package.sell_price),
                "line_price": str(package.line_price),
                "points_num": package.points_num,
                "train_num": package.train_num,
                "robot_num": package.robot_num,
                "know_num": package.know_num
            }, ensure_ascii=False)
        )

        return schema.RechargePlaceVo(
            order_id=order.id,
            paid_amount=package.sell_price
        )

    @classmethod
    async def billing(cls, user_id: int, params: schema.BillSearchIn) -> PagingResult[schema.RechargeBillingVo]:
        """
        充值账单

        Args:
            user_id (int): 用户ID。
            params (schema.BillSearchIn): 搜索参数。

        Returns:
            PagingResult[schema.RechargeBillingVo]: 分页账单Vo。

        Author:
            zero
        """
        # 查询条件
        where = RechargeOrderModel.build_search({
            "datetime": ["start_time|end_time@create_time"]
        }, params.__dict__)

        where.append(Q(user_id=user_id))
        where.append(Q(pay_status=PayEnum.PAID_OK))

        # 查询数据
        _model = RechargeOrderModel.filter(*where).order_by("-id", "-pay_time")
        _pager = await RechargeOrderModel.paginate(
            model=_model,
            page_no=params.page_no,
            page_size=params.page_size,
            datetime_field=["create_time", "update_time", "pay_time"],
        )

        # 处理数据
        _lists = []
        for item in _pager.lists:
            snapshot = json.loads(item["snapshot"] or "{}")
            _lists.append(schema.RechargeBillingVo(
                order_sn=item["order_sn"],
                pay_way=PayEnum.get_pay_way_msg(item["pay_way"]),
                pay_status=PayEnum.get_pay_status_msg(item["pay_status"]),
                package_name=snapshot.get("name", "-"),
                points_num=item["points_num"],
                train_num=item["train_num"],
                robot_num=item["robot_num"],
                know_num=item["know_num"],
                order_amount=item["order_amount"],
                paid_amount=item["paid_amount"],
                pay_time=item["pay_time"],
                create_time=item["create_time"]
            ))

        _pager.lists = _lists
        return _pager
